
package FrameWork;

import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.media.opengl.glu.GLU;
import utils.Matrix;
import utils.MatrixOps;

/**
 *
 * @author trong_000
 */
public class NewCamera implements MouseListener, MouseMotionListener, KeyListener{
    public double topX = 0.0f;
    public double topY = 1.0f;
    public double topZ = 0.0f;

    public double eyeX = 0.0f;
    public double eyeY = 0.5f;
    public double eyeZ = 1.0f;

    public static double dist = 5;
    
    public int a = 0;
    
    private float view_rotx = 0.0f;
    //private float view_roty = 0.0f; // CHECK

    private int prevMouseX;
    private int prevMouseY;
    
    public NewCamera(){
        
    }
    
    public void update(GLU glu){
        double eyeDstX = eyeX * dist;
        double eyeDstY = eyeY * dist;
        double eyeDstZ = eyeZ * dist;

        glu.gluLookAt(eyeDstX, eyeDstY, eyeDstZ, 0, 0, 0, topX, topY, topZ);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        
    }

    @Override
    public void mousePressed(MouseEvent e) {
        prevMouseX = e.getX();
        prevMouseY = e.getY();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        
    }

    @Override
    public void mouseExited(MouseEvent e) {
        
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();
        Dimension size = e.getComponent().getSize();

        float thetaY = 360.0f * ((float) (prevMouseX - x) / (float) size.width);
        float thetaX = 360.0f * ((float) (prevMouseY - y) / (float) size.height);

        prevMouseX = x;
        prevMouseY = y;

        if ((view_rotx - thetaX) > +60) {
          thetaX = view_rotx - 60;
        }

        if ((view_rotx - thetaX) < -60) {
          thetaX = view_rotx + 60;
        }

        view_rotx -= thetaX;
        //view_roty += thetaY;

        rotate(thetaX, thetaY);
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        
    }
    
    public void rotate(float thetaX, float thetaY) {
        Matrix curEye = new Matrix(4, 1);
        curEye.setData( //
            new double[]{eyeX, eyeY, eyeZ, 1});

        Matrix curTop = new Matrix(4, 1);
        curTop.setData( //
            new double[]{topX, topY, topZ, 1});

        Matrix ry = MatrixOps.rotateY(thetaY);

        Matrix newEye = MatrixOps.matrixMult(ry, curEye);
        Matrix newTop = MatrixOps.matrixMult(ry, curTop);

        curEye = newEye;
        curTop = newTop;

        Matrix curSid = MatrixOps.crossProduct(curEye, curTop);

        Matrix rs = MatrixOps.rotate( //
            -thetaX, curSid.get(0, 0), curSid.get(1, 0), curSid.get(2, 0));

        newEye = MatrixOps.matrixMult(rs, curEye);
        newTop = MatrixOps.matrixMult(rs, curTop);

        eyeX = newEye.get(0, 0);
        eyeY = newEye.get(1, 0);
        eyeZ = newEye.get(2, 0);

        topX = newTop.get(0, 0);
        topY = newTop.get(1, 0);
        topZ = newTop.get(2, 0);
    }

    @Override
    public void keyTyped(KeyEvent e) {
        
    }

    @Override
    public void keyPressed(KeyEvent e) {
        
    }

    @Override
    public void keyReleased(KeyEvent e) {
        
    }

    public void rotateAlpha(int beta){
        
        if(a < beta)
            a++;
        else
            return;
        eyeZ = Math.cos(Math.toRadians(a));
        eyeX = Math.sin(Math.toRadians(a));
    }
}
